package org.linlinjava.litemall.core.template;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallOrder;
import org.linlinjava.litemall.db.domain.LitemallOrderGoods;
import org.linlinjava.litemall.db.domain.LitemallShop;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.domain.WxMsgReplyMerchant;
import org.linlinjava.litemall.db.domain.WxMsgReplyUser;
import org.linlinjava.litemall.db.domain.WxTemplateMsgLog;
import org.linlinjava.litemall.db.domain.WxUser;
import org.linlinjava.litemall.db.service.LitemallOrderGoodsService;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.service.LitemallShopService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.db.service.MsgReplyUserService;
import org.linlinjava.litemall.db.service.WxMsgReplyMerchantService;
import org.linlinjava.litemall.db.service.WxTemplateMsgLogService;
import org.linlinjava.litemall.db.service.WxUserService;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.binarywang.wx.miniapp.api.WxMaService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage.MiniProgram;

@Service
public class WxMpMsgTemplateService {

	@Autowired
	private WxMpService wxMpService;
	@Autowired
	private WxMaService wxMaService;
	@Autowired
	private MsgReplyUserService msgReplyUserService;
	@Autowired
	private LitemallOrderService orderService;
	@Autowired
	private LitemallShopService shopService;
	@Autowired
	private LitemallUserService  userService;
	@Autowired
	private WxUserService wxuserService; 
	@Autowired
	private WxTemplateMsgLogService wxTemplateMsgLogService;
	@Autowired
	private WxMsgReplyMerchantService wxMsgReplyMerchantService;
	@Autowired
	private LitemallOrderGoodsService orderGoodsService;
	
	
    @Async
    public void pushReminderToUser(WxUser wxUser) {
    	LitemallUser user = userService.queryByUnionId(wxUser.getUnionId());
    	if(user != null) {
    		//查询订单信息，查询今天的订单
    		List<LitemallOrder> orderInfo = orderService.ReminderOrderInfo(user.getId());
    		if(orderInfo == null) {
    			return;
    		}
    		if(orderInfo.size()<1) {
    			return;
    		}
    		//查询商家
    		LitemallShop shopInfo = shopService.getOneByShopID(orderInfo.get(0).getShopId());
    		
    		WxMpTemplateMessage templateMessage = null;
    		List<WxMpTemplateData> listDate = Arrays.asList();
    		
    		templateMessage = WxMpTemplateMessage.builder()
    				.toUser(wxUser.getOpenId())
    				.templateId("0r_MKFkSIdkuSjt9q3755DNOsoJmLASHVhfs1-XpA_Q")
    				.url("")
    				.build();
    		listDate = Arrays.asList(
    				new WxMpTemplateData("first", "您的订单("+ orderInfo.get(0).getOrderSn() +")催单已经处理", "#38A7F0"),
    				new WxMpTemplateData("keyword1", "平台正在催促配送员", "#38A7F0"),
    				new WxMpTemplateData("keyword2", shopInfo.getShopPhone(), "#38A7F0"),
    				new WxMpTemplateData("remark", "如果您非常急，也可以打电话给商家催促。", "#38A7F0"));
    		
    		if(templateMessage != null) {
    			templateMessage.setData(listDate);
    			// 发送模版消息
    			sendTemplateMsg(templateMessage);
    			pushReminderToAdmin(orderInfo.get(0),shopInfo);
    		}
    	}
    }
    
    public void pushReminderToAdmin(LitemallOrder orderInfo,LitemallShop shopInfo) {
		WxMpTemplateMessage templateMessage = null;
		List<WxMpTemplateData> listDate = Arrays.asList();
		List<WxMsgReplyUser> msgReplyList = msgReplyUserService.querySelective("reminder");
		if(msgReplyList.size()>0) {
			for(int i=0;i<msgReplyList.size();i++) {
				String ttype = msgReplyList.get(i).getMsgType();
				if (ttype.equals("reminder")) {//用户订阅 ttype=subscribe
					templateMessage = WxMpTemplateMessage.builder()
							.toUser(msgReplyList.get(i).getMpOpenId())
							.templateId("UQYAJDno9fH6OX2NjytV7ux9NHHjdbZ-JO5eaXDUiPE")
							.url("")
							.build();
					listDate = Arrays.asList(
							new WxMpTemplateData("first","催单商家："+ shopInfo.getShopName() +"", "#38A7F0"),
							new WxMpTemplateData("keyword1", orderInfo.getOrderSn(), "#63c1e4"),
							new WxMpTemplateData("keyword2", OrderUtil.orderStatusText(orderInfo) + "("+orderInfo.getShipSn()+")", "#63c1e4"),
							new WxMpTemplateData("keyword3", "***", "#63c1e4"),
							new WxMpTemplateData("remark", orderInfo.getAddress(), "#63c1e4"));
				} 
				if(templateMessage != null) {
					templateMessage.setData(listDate);
					// 发送模版消息
					sendTemplateMsg(templateMessage);
				}
			}
		}
    }
    

	/**
	 * 公众号推送订单信息给商家
	 * @param orderSn
	 */
	@Async
	public void pushOrderInfoByMerchant(String orderSn,Integer shipSn) {
		
		WxMpTemplateMessage templateMessage = null;
		List<WxMpTemplateData> listDate = Arrays.asList();
		LitemallOrder orderDetail = getOrderDetail(orderSn);
		//推送商家信息
		WxMsgReplyMerchant wt = wxMsgReplyMerchantService.findByShop(orderDetail.getShopId());
		if(wt == null) {
			return;
		}
		List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderDetail.getId());
		String detail = "";
		for(int j=0;j<orderGoodsList.size();j++) {
			detail = detail + orderGoodsList.get(j).getGoodsName() + " *" + orderGoodsList.get(j).getNumber()+"\r\n";
		}
		
		String msg = "送上宿舍";
		if(orderDetail.getDeliverystatus() == 0) {
			msg = "侧门自取";
		}
		
		templateMessage = WxMpTemplateMessage.builder()
				.toUser(wt.getMpOpenId())
				.templateId("AK8N1z8ZHj5GIC_UOFQ1StzYDT6L4Ck98XgU3X1jN6Y")
				.url("")
				.build();
		listDate = Arrays.asList(
				new WxMpTemplateData("keyword1", detail, "#38A7F0"),
				new WxMpTemplateData("keyword2", StringUtils.isEmpty(orderDetail.getPayTime())?getTime():getNewTime(orderDetail.getPayTime()), "#38A7F0"),
				new WxMpTemplateData("keyword3", orderDetail.getAddress() + " " + msg, "#38A7F0"),
				new WxMpTemplateData("keyword4", orderDetail.getConsignee()+"("+orderDetail.getMobile()+")", "#38A7F0"),
				new WxMpTemplateData("keyword5", "已付款(#"+shipSn+")", "#38A7F0"),
				new WxMpTemplateData("remark", orderDetail.getMessage()+" ", "#38A7F0"));
		
		if(templateMessage != null) {
			templateMessage.setData(listDate);
			// 发送模版消息
			sendTemplateMsg(templateMessage);
		}
		
	}
	
	
	/**
	 * 公众号推送退款订单信息给商家
	 * @param orderSn
	 */
	@Async
	public void pushRefundOrderInfoByMerchant(String orderSn) {
		
		WxMpTemplateMessage templateMessage = null;
		List<WxMpTemplateData> listDate = Arrays.asList();
		LitemallOrder orderDetail = getOrderDetail(orderSn);
		//推送商家信息
		WxMsgReplyMerchant wt = wxMsgReplyMerchantService.findByShop(orderDetail.getShopId());
		if(wt == null) {
			return;
		}
		templateMessage = WxMpTemplateMessage.builder()
				.toUser(wt.getMpOpenId())
				.templateId("KAU2_IjJOV5M7f8ZBeX9przUdd1vwpwcRMUMGsyi5Og")
				.url("")
				.build();
		listDate = Arrays.asList(
				new WxMpTemplateData("keyword1", "快当外卖", "#38A7F0"),
				new WxMpTemplateData("keyword2", orderDetail.getOrderSn(), "#38A7F0"),
				new WxMpTemplateData("keyword3", orderDetail.getActualPrice().toString(), "#38A7F0"),
				new WxMpTemplateData("keyword4", "无", "#38A7F0"),
				new WxMpTemplateData("remark", "订单序号："+orderDetail.getShipSn(), "#38A7F0"));
		
		if(templateMessage != null) {
			templateMessage.setData(listDate);
			// 发送模版消息
			sendTemplateMsg(templateMessage);
		}
		
	}
	
	/**
	 * 主动推送 用于用户关注、订单下单通知、订单退款等
	 * 
	 * @param toUser
	 * @param templateId
	 * @param url
	 * @param TemplateType
	 */
	@Async
	public void activeSend(WxMpUser wxmpUser,String TemplateType,Boolean newANDold,String orderSn,String orderType) {
		WxMpTemplateMessage templateMessage = null;
		List<WxMpTemplateData> listDate = Arrays.asList();
		LitemallOrder orderDetail = null;
		//LitemallShop shopDetail = null;
		if(TemplateType.equals("newOrder")) {
			orderDetail = getOrderDetail(orderSn);
			//shopDetail = shopService.getOneByShopID(orderDetail.getShopId());
		}
		
		List<WxMsgReplyUser> msgReplyList = msgReplyUserService.querySelective(TemplateType);
		if(msgReplyList.size()>0) {
			for(int i=0;i<msgReplyList.size();i++) {
				String ttype = msgReplyList.get(i).getMsgType();
				if (ttype.equals("subscribe")) {//用户订阅 ttype=subscribe
					templateMessage = WxMpTemplateMessage.builder()
							.toUser(msgReplyList.get(i).getMpOpenId())
							.templateId("ZViz3GPOVCNw_GdAfb2uryi2r0_VutJ54x2hEoP5jHQ")
							.url("")
							.build();
					listDate = Arrays.asList(
							// new WxMpTemplateData("first","123", "#38A7F0"),
							new WxMpTemplateData("keyword1", wxmpUser.getNickname(), "#63c1e4"),
							new WxMpTemplateData("keyword2", getTime(), "#63c1e4"),
							new WxMpTemplateData("keyword3", "快当外卖", "#63c1e4"),
							new WxMpTemplateData("remark", newANDold?"新用户":"老用户", "#63c1e4"));
				} else if(ttype.equals("newOrder")) {//新订单推送 ttype=newOrder
					
					//推送商家信息
					WxMsgReplyMerchant wt = wxMsgReplyMerchantService.findByShop(orderDetail.getShopId());
					if(wt == null) {
						return;
					}
					List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderDetail.getId());
					String detail = "";
					for(int j=0;j<orderGoodsList.size();j++) {
						detail = detail + orderGoodsList.get(j).getGoodsName() + " *" + orderGoodsList.get(j).getNumber();
					}
					
					
					templateMessage = WxMpTemplateMessage.builder()
							.toUser(wt.getMpOpenId())
							.templateId("AK8N1z8ZHj5GIC_UOFQ1StzYDT6L4Ck98XgU3X1jN6Y")
							.url("")
							.build();
					listDate = Arrays.asList(
							new WxMpTemplateData("keyword1", detail, "#38A7F0"),
							new WxMpTemplateData("keyword2", StringUtils.isEmpty(orderDetail.getPayTime())?getTime():getNewTime(orderDetail.getPayTime()), "#38A7F0"),
							new WxMpTemplateData("keyword3", orderDetail.getAddress(), "#38A7F0"),
							new WxMpTemplateData("keyword4", orderDetail.getConsignee(), "#38A7F0"),
							new WxMpTemplateData("keyword5", "已付款", "#38A7F0"),
							new WxMpTemplateData("remark", "用户备注："+orderDetail.getMessage(), "#38A7F0"));
				}
				if(templateMessage != null) {
					templateMessage.setData(listDate);
					// 发送模版消息
					sendTemplateMsg(templateMessage);
				}
			}
		}

	}

	/**
	 * 手动推送 用于订单发货、订单提醒等
	 * 
	 * @param orderSn
	 * @param msg	
	 */
	public Object manualSend(String orderSn,String msg,String openId) {
		if(StringUtils.isEmpty(orderSn)) {
			return ResponseUtil.custom("orderSn:"+ orderSn + "错误！");
		}
		//订单派单
		LitemallOrder orderDetail = getOrderDetail(orderSn);
		WxUser wxuser = new WxUser();
		if(StringUtils.isEmpty(openId)) {
			LitemallUser u = userService.findById(orderDetail.getUserId());
			if(StringUtils.isEmpty(u.getUnionid())) {
				return ResponseUtil.custom("Unionid: 错误！");
			}
			wxuser = wxuserService.getUserByUnionId(u.getUnionid());
			if(wxuser == null) {
				return ResponseUtil.custom("WxUser: 错误！");
			}
			if(!wxuser.getSubscribe()) {
				return ResponseUtil.custom("Subscribe: 错误！");
			}
		}else {
			wxuser.setOpenId(openId);
		}
		
		MiniProgram m = new MiniProgram();
		m.setAppid(wxMaService.getWxMaConfig().getAppid());
		m.setPagePath("/pages/ucenter/order/order");
		WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
				.toUser(wxuser.getOpenId())
				.templateId("nAMURYgMeCs1m2E8RzIhm51wLwPCQncXOD5zPQKomZU")
				.miniProgram(m)
				//.url("/pages/ucenter/order/order")
				.build();
		List<WxMpTemplateData> listDate = Arrays.asList(
				new WxMpTemplateData("keyword1", StringUtils.isEmpty(orderDetail.getPayTime())?getNewTime(orderDetail.getAddTime()):getNewTime(orderDetail.getPayTime()), "#38A7F0"),
				new WxMpTemplateData("keyword2", "订单派单", "#38A7F0"),
				new WxMpTemplateData("remark", StringUtils.isEmpty(msg)?"您在平台的订单已派单，请于(17:30 - 18：30)时间段在民大相思湖校区西门领取；其他地区请忽略！":msg, "#38A7F0"));
		
		templateMessage.setData(listDate);
		// 推送模版消息
		//pushTemplateMsg(templateMessage);
		
		String result;
		Boolean res = true;
		try {
			result = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
		} catch (WxErrorException e) {
			result = e.getMessage();
			res = false;
		}
		//保存消息推送日志
		saveTemplateLog(templateMessage,result);
		if(res) {
			return ResponseUtil.ok();
		}
		return ResponseUtil.custom("推送: 错误！");
	}
	
	private void saveTemplateLog(WxMpTemplateMessage templateMessage,String result) {
		//保存消息推送日志
		WxTemplateMsgLog templateLog = new WxTemplateMsgLog();
		templateLog.setTouser(templateMessage.getToUser());
		templateLog.setTemplateId(templateMessage.getTemplateId());
		templateLog.setUrl(templateMessage.getUrl());
		templateLog.setMiniprogram(templateMessage.getMiniProgram().toString());
		templateLog.setMsgData(templateMessage.getData().toString());
		templateLog.setSendTime(LocalDateTime.now());
		templateLog.setSendResult(result);
		wxTemplateMsgLogService.saveLog(templateLog);
	}
	
	@Async
	public void sendTemplateMsg(WxMpTemplateMessage msg) {
		try {
			wxMpService.getTemplateMsgService().sendTemplateMsg(msg);
		} catch (WxErrorException e) {
			e.getMessage();
		}
	}

	public LitemallOrder getOrderDetail(String orderSn) {
		return orderService.findBySn(orderSn);
	}
	
	public String getTime() {
		Date date = new Date();
		String strDateFormat = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
		return sdf.format(date);
	}
	
	public String getNewTime(LocalDateTime localDateTime) {
		String strDateFormat = "yyyy-MM-dd HH:mm:ss";
		DateTimeFormatter sdf = DateTimeFormatter.ofPattern(strDateFormat);
		return sdf.format(localDateTime);
	}

}
